#import cpptomips_final

import global_variables

HashSize=4
KEYWORD= 500
T_Int = "int"
T_Float	="float"
T_Char 	="char"
T_Bool 	="bool"
T_Error	="error"
T_Void	="void"
T_String="const char *"
T_Label	="label"
T_Namespace= "namespace"
T_Class	="class"
T_CharPtr= "char *"

currentDepth = 0

T_LEN=100	
MAXDEPTH= 100   
#########################################################################
#define CMP(a,b) (strcmp(a, b)? 0: 1)
#define ASSIGN(a,b) strcpy(a, b)
#########################################################################

class Attr:
	def __init__(self):
		self.Type= ""
		self.Public= 0
		self.Private = 0
		self.Pointer = 0		
		self.Integer = 0
		self.Float = 0		#for both double and float, distinguished by checking width
		self.Char = 0
		self.Bool = 0
		self.Dimension = 0	# True if variable is array
		self.limit = 0		# upper limit of array (valid if DIMENSION is true)
		self.width = 0
		self.Void = 0
		self.Enum = 0
		self.Typename = 0
		self.Const = 0
		self.ptrConst = 0
		self.ptr = 0
		self.Signed = 0
		self.Unsigned = 0
		self.Static = 0
		self.Extern = 0
		self.Short = 0
		self.Long = 0
		self.String = 0
		self.scope = 0
		self.IntConstValue=0		# because this g++ compiler set 4 byte for long but we are setting 8 bytes
		self.IntConst=0
		self.FloatConstValue=0			# to store the value of double or float
		self.StringValue=""
		self.code=""	#For intermediate code generation	 
		self.lvalue = 0			# 0 means not
		self.doubleptr = 0
		self.stackOffset = 0
		self.functionFlag = 0   


class SynAttr:
	def __init__(self):
		self.Type = ""
		self.limit = 0	# limit for array both
		self.temp = 0
		self.width = 0
		self.Const = 0
		self.ptrConst = 0
		self.doubleptrConst = 0
		self.ptr = 0
		self.Unsigned = 0
		self.Signed = 0
		self.Short = 0
		self.Long = 0
		self.lexeme = ""
		self.scope= ""
		self.IntConst = 0
		self.IntConstValue = 0			# set in case of array size,
		self.FloatConstValue = 0
		self.StringValue =""
		self.code = ""	 
		self.stackOffset = 0   
		self.lvalue = 0			# 0 means value
		self.doubleptr = 0
		self.functionFlag = 0  
		self.op = ""

class ListNode:
	def __init__(self):
		self.lexeme=""
		self.Type=0
		self.keyWordNum=0
		self.scopeNum=0
		self.NextNode=None
		self.line_number=0	#line_number where identifier is declared or class/namespace declaration


class VALUE:
	def __init__(self):
		self.intValue= 0
		self.longIntValue= 0
		self.floatValue = 0.0
		self.doubleValue = 0.0
		self.charValue = ""
		self.string = ""


class symentry:
	def __init__(self):
		self.idName= "" 	#Identifier name
		self.v= None	#Its value
		self.scope= ""	#Its scope
		self.labelScope=""	#If idName is a lebel, scope contains "label". So this is the scope to which the label belongs.
		self.type= ""	#Its type
		self.width = 0
		self.next= None	#pointer to next node
		self.Const= 0			# store whether identifier is const or not
		self.ptrConst= 0		# store const pointer 
		self.doubleptr= 0			#nkbansal
		self.doubleptrConst= 0			#nkbansal
		self.IntConst= 0		#enumerated identifiers are Integer constant can be used any where just like literal constants
		self.stackOffset= 0	   
		self.heapOffset= 0 
		self.ptr= 0
		self.functionFlag= 0
		self.functionOverloading= 0 #free slot index of overloaded functions put at same node in scopeTable
		self.parameterList = [""]  #parameter list
		self.definitionFlag= [0]  #has the function been declared
		self.returntype= ""
		self.functionDeclareFlag= 0
		self.activationRecordSize= 0


#char *yyt;	//To be able to  access yytext in parser.
scopeTable= []
def initScopeTable():
	for i in range(HashSize):
		newNode= symentry()
		scopeTable.append(newNode)

symbolTable= []
for i in range(HashSize):
	newNode= symentry()
	scopeTable.append(newNode)	
	
linecount=0

def Insert(value,t):
	newNode= ListNode()
	newNode.lexeme= value
	newNode.Type=t
	newNode.NextNode= SymbolTable[value[0]%HashSize]
	SymbolTable[value[0]%HashSize]=newNode
	return newNode
		
def Lookup(value):
	newNode= ListNode()
	newNode= SymbolTable[value[0]%HashSize]
	while ((newNode!=Null) and (newNode.lexeme != value)):
		newNode= newNode.NextNode
	if newNode!=Null :
		return newNode
	return Null

def InitializeSymbolTable():
	#for i in range(HashSize):
	#	SymbolTable[i]= Null
	p= Insert("sizeof",KEYWORD)
	p.keyWordNum = SIZEOF
	p = Insert("new",KEYWORD)
	p.keyWordNum = NEW
	p = Insert("operator",KEYWORD)
	p.keyWordNum =  OPERATOR 
	p = Insert("this",KEYWORD)
	p.keyWordNum =  THIS 
	p = Insert("throw",KEYWORD)
	p.keyWordNum =  THROW 
	p = Insert("delete",KEYWORD)
	p.keyWordNum =  DELETE 
	p = Insert("true",KEYWORD)
	p.keyWordNum =  TRU 
	p = Insert("false",KEYWORD)
	p.keyWordNum =  FALS 
	p = Insert("auto",KEYWORD)
	p.keyWordNum =  AUTO 
	p = Insert("const",KEYWORD)
	p.keyWordNum =  CONST 
	p = Insert("double",KEYWORD)
	p.keyWordNum =  _DOUBLE 
	p = Insert("float",KEYWORD)
	p.keyWordNum =  _FLOAT 
	p = Insert("int",KEYWORD)
	p.keyWordNum = INT
	p = Insert("short",KEYWORD)
	p.keyWordNum =  SHORT 
	p = Insert("struct",KEYWORD)
	p.keyWordNum =  STRUCT 
	p = Insert("unsigned",KEYWORD)
	p.keyWordNum =  UNSIGNED 
	p = Insert("break",KEYWORD)
	p.keyWordNum =  BREAK 
	p = Insert("continue",KEYWORD)
	p.keyWordNum =  CONTINUE 
	p = Insert("else",KEYWORD)
	p.keyWordNum =  ELSE 
	p = Insert("for",KEYWORD)
	p.keyWordNum =  FOR 
	p = Insert("long",KEYWORD)
	p.keyWordNum =  LONG 
	p = Insert("signed",KEYWORD)
	p.keyWordNum =  SIGNED 
	p = Insert("switch",KEYWORD)
	p.keyWordNum =  SWITCH 
	p = Insert("void",KEYWORD)
	p.keyWordNum =  VOID 
	p = Insert("case",KEYWORD)
	p.keyWordNum =  CASE 
	p = Insert("default",KEYWORD)
	p.keyWordNum =  DEFAULT 
	p = Insert("enum",KEYWORD)
	p.keyWordNum =  ENUM 
	p = Insert("goto",KEYWORD)
	p.keyWordNum =  GOTO 
	p = Insert("typedef",KEYWORD)
	p.keyWordNum =  TYPEDEF 
	p = Insert("char",KEYWORD)
	p.keyWordNum =  _CHAR 
	p = Insert("do",KEYWORD)
	p.keyWordNum =  DO 
	p = Insert("extern",KEYWORD)
	p.keyWordNum =  EXTERN 
	p = Insert("if",KEYWORD)
	p.keyWordNum =  IF 
	p = Insert("return",KEYWORD)
	p.keyWordNum =  RETURN 
	p = Insert("static",KEYWORD)
	p.keyWordNum =  STATIC 
	p = Insert("union",KEYWORD)
	p.keyWordNum =  UNION 
	p = Insert("while",KEYWORD)
	p.keyWordNum =  WHILE 
	p = Insert("namespace",KEYWORD)
	p.keyWordNum =  NAMESPACE 
	p = Insert("try",KEYWORD)
	p.keyWordNum =  TRY 
	p = Insert("bool",KEYWORD)
	p.keyWordNum =  BOOL 
	p = Insert("static_cast",KEYWORD)
	p.keyWordNum =  STATIC_CAST 
	p = Insert("typeid",KEYWORD)
	p.keyWordNum =  TYPEID 
	p = Insert("catch",KEYWORD)
	p.keyWordNum =  CATCH 
	p = Insert("template",KEYWORD)
	p.keyWordNum =  TEMPLATE 
	p = Insert("class",KEYWORD)
	p.keyWordNum =  CLASS 
	p = Insert("private",KEYWORD)
	p.keyWordNum =  PRIVATE 
	p = Insert("using",KEYWORD)
	p.keyWordNum =  USING 
	p = Insert("const_cast",KEYWORD)
	p.keyWordNum =  CONST_CAST 
	p = Insert("public",KEYWORD)
	p.keyWordNum =  PUBLIC 
	p = Insert("protected",KEYWORD)
	p.keyWordNum =  PROTECTED 
	p = Insert("wchar_t",KEYWORD)
	p.keyWordNum =  WCHART 
	p = Insert("and",KEYWORD)
	p.keyWordNum =  AND 
	p = Insert("bitand",KEYWORD)
	p.keyWordNum =  BITAND 
	p = Insert("compl",KEYWORD)
	p.keyWordNum =  COMPL 
	p = Insert("not_eq",KEYWORD)
	p.keyWordNum =  NOT_EQ 
	p = Insert("or_eq",KEYWORD)
	p.keyWordNum =  OR_EQ 
	p = Insert("xor_eq",KEYWORD)
	p.keyWordNum =  XOR_EQ 
	p = Insert("and_eq",KEYWORD)
	p.keyWordNum =  AND_EQ 
	p = Insert("bitor",KEYWORD)
	p.keyWordNum =  BITOR 
	p = Insert("not",KEYWORD)
	p.keyWordNum =  NOT 
	p = Insert("or",KEYWORD)
	p.keyWordNum =  OR 
	p = Insert("xor",KEYWORD)
	p.keyWordNum =  XOR 




def assign(attr1,attr2):
	attr1.Type = attr2.Type
	attr1.Public = attr2.Public
	attr1.Private = attr2.Private
	attr1.Pointer = attr2.Pointer
	attr1.Integer = attr2.Integer
	attr1.Float = attr2.Float
	attr1.Char = attr2.Char
	attr1.Bool = attr2.Bool
	attr1.Dimension = attr2.Dimension
	attr1.limit = attr2.limit
	attr1.width = attr2.width
	attr1.Void = attr2.Void
	attr1.Enum = attr2.Enum
	attr1.Typename = attr2.Typename
	attr1.Const = attr2.Const
	attr1.Unsigned = attr2.Unsigned
	attr1.Signed = attr2.Signed
	attr1.Static = attr2.Static
	attr1.Extern = attr2.Extern
	attr1.Short = attr2.Short
	attr1.Long = attr2.Long
	attr1.String = attr2.String

def Assign(synattr1, synattr2):
	if synattr2==None :
		synattr2=SynAttr()
	synattr1.Type = synattr2.Type
	synattr1.limit = synattr2.limit
	synattr1.temp = synattr2.temp	
	synattr1.width = synattr2.width
	synattr1.Const = synattr2.Const
	synattr1.IntConst = synattr2.IntConst
	synattr1.lexeme= synattr2.lexeme
	synattr1.scope = synattr2.scope
	

def merge(dest,attr1,attr2):
	if((attr1.Type == T_Error)):
		dest.Type = T_Error
	if((attr2.Public and attr1.Public) or (attr2.Public and attr1.Private) or (attr2.Public and attr2.Private)):
		dest.Type = T_Error	
	if ((attr1.Public and attr2.Private)or(attr1.Public and attr1.Private) or (attr2.Private and attr1.Private)):
		dest.Type = T_Error
	if(attr2.Dimension and attr1.Dimension):
		dest.Type = T_Error
	if(attr2.Typename):
		if(attr1.Integer or attr1.Char or attr1.Float or attr1.Bool or attr1.Void or attr1.Enum):
		 	dest.Type = T_Error
		if(attr1.Typename or attr1.Const or attr1.Unsigned or attr1.Signed or attr1.Long):
	 		dest.Type = T_Error
		if(attr1.Short or attr1.String):
			dest.Type = T_Error
	if (attr1.Typename):
	 	if (attr2.Integer or attr2.Char or attr2.Float or attr2.Bool or attr2.Void or attr2.Enum or attr2.Typename):
			dest.Type = T_Error	 	
	 	if (attr2.Const or attr2.Unsigned or attr2.Signed or attr2.Long or attr2.Short or attr2.String):
			dest.Type = T_Error
	else: 
		dest.Public = attr2.Public or attr1.Public
        	dest.Private = attr2.Private or attr1.Private
        	dest.Pointer = attr2.Pointer or attr1.Pointer
        	dest.Integer = attr2.Integer or attr1.Integer
        	dest.Float = attr2.Float or attr1.Float
        	dest.Char = attr2.Char or attr1.Char
        	dest.Bool = attr2.Bool or attr1.Bool
        	dest.Dimension = attr2.Dimension or attr1.Dimension

		dest.Void = attr2.Void or attr1.Void
		dest.Enum = attr2.Enum or attr1.Enum
		dest.Typename = attr2.Typename or attr1.Typename
		dest.Const = attr2.Const or attr1.Const
		dest.Static = attr2.Static or attr1.Static
		dest.Extern = attr2.Extern or attr1.Extern
		dest.Unsigned = attr2.Unsigned or attr1.Unsigned
		dest.Signed = attr2.Signed or attr1.Signed
		dest.Long = attr2.Long or attr1.Long
		dest.Short = attr2.Short or attr1.Short
		dest.String = attr2.String or attr1.String
        	if (attr1.Dimension):
        	        dest.limit = attr1.limit
        	elif(attr2.Dimension):
        	        dest.limit = attr2.limit
		if(attr2.Pointer or attr1.Pointer):
			dest.width = 4
		elif(attr2.width!=4 and attr2.width!=0) :	# 4 is default no need to assign
        		dest.width = attr2.width
		elif(attr1.width!=4 and attr2.width!=0):
			 dest.width = attr1.width	
		else :
			dest.width = 4			#default width
        return dest
  
 
def Merge(dest,attr1,attr2): 
	if(attr1.Type == T_Error): 
		dest.Type = T_Error
	elif(attr2.width!=4 and attr2.width!=0): 	# 4 is default no need to assign
		dest.width = attr2.width
	elif(attr1.width!=4 and attr2.width!=0):
		dest.width = attr1.width	
	else :
		dest.width = 4			#default width
	dest.Const= attr1.Const or attr2.Const
	dest.IntConst =  attr1.IntConst and attr2.IntConst
	dest.ptrConst = attr1.ptrConst and attr2.ptrConst
	dest.doubleptrConst = attr1.doubleptrConst and attr2.doubleptrConst
	dest.ptr = attr1.ptr and attr2.ptr
	dest.Unsigned = attr1.Unsigned and attr2.Unsigned
	dest.Signed = attr1.Signed and attr2.Signed
	dest.Short = attr1.Short and attr2.Short
	dest.Long = attr1.Long and attr2.Long
	dest.doubleptr = attr1.doubleptr and attr2.doubleptr
	dest.functionFlag = attr1.functionFlag and attr2.functionFlag
	return dest


def highest_CommonType(synattr1,synattr2,dest):
	if((synattr1.Type == T_Float) or (synattr2.Type == T_Float)):
		dest.Type = T_Float
		if(synattr1.width > synattr2.width):
			dest.width = synattr1.width
		else:
			dest.width = synattr2.width
	elif((synattr1.Type == T_Int) or (synattr2.Type == T_Int)) :
		dest.Type = T_Int
		if(synattr1.width>synattr2.width):
			dest.width = synattr1.width
		else:
			dest.width = synattr2.width
	elif((synattr1.Type == T_Char) or (synattr2.Type == T_Char)):
		dest.Type = T_Char
		dest.width = 1
	elif((synattr1.Type == T_Bool) or (synattr2.Type == T_Bool)):		#constucted type are not handled
		dest.Type = T_Bool
		dest.width = 1
	elif(((synattr1.Type==T_String) and (synattr2.Type == T_CharPtr)) or ((synattr1.Type == T_CharPtr) and (synattr2.Type == T_String)) or ((synattr1.Type == T_String) and (synattr2.Type== T_String))):
		dest.Type = T_String	# assigning const char * type to dest
		dest.width = 4
	else:
		dest.Type= T_Error
	return dest
	

def type_Check(synattr1,synattr2):
	if(synattr1.ptr != synattr2.ptr):
		return 0
	elif(synattr1.doubleptr != synattr2.doubleptr):
		return 0
	elif((synattr1.Type == synattr2.Type)):
		if(synattr1.ptr):			#types of pointer must match strictly
			if(synattr1.Const != synattr2.Const or synattr1.Unsigned != synattr2.Unsigned or synattr1.Long != synattr2.Long or synattr1.Short != synattr2.Short or synattr1.width!=synattr2.width ):
				return 0
		elif(synattr1.doubleptr):
			if(synattr1.ptrConst != synattr2.ptrConst or synattr1.Unsigned != synattr2.Unsigned or synattr1.Long != synattr2.Long or synattr1.Short != synattr2.Short or synattr1.width!=synattr2.width):
				return 0
		else:
			return 1
	else:
		return 0
	return 1
	
	
def TypeString(syn):
	Type = ""
	#Type[0]='\0'
	if(syn.Unsigned ):
		Type = "unsigned "
	if(syn.Long):
		strcat(Type,"long int")
	elif(syn.Short):
		strcat(Type,"short int")
	elif((syn.Type == T_Int)):
		strcat(Type,"int")
	elif((syn.Type == T_Char)):
		if(syn.width==1):
			strcat(Type,"char")
		elif(syn.width==2):
			strcat(Type,"wchar_t")
		else:
			print "Line" ,linecount, ": error: error in type computation.\n"
	elif((syn.Type == T_Bool)):
		strcat(Type,"bool")
	elif((syn.Type == T_Float)):
		if(syn.width==4):
			strcat(Type,"float")
		elif(syn.width==8):
			strcat(Type,"double")
		else:
			print "Line" ,linecount, ": error: error in type computation.\n"
	#elif(syn.Type[0] != '\0'):
	elif(syn.Type != ""):
		Type = syn.Type
	else:
		Type= "void"
	if(syn.ptr):
		Type = "*"
	if(syn.doubleptr) :
		strcat(Type,"*")
	result = ""
	result = Type
	return result
	

def SynAttrType(syn):
	Type =""
	Type[0]='\0'
	if(syn.Unsigned ):
		Type = "unsigned "
	if(syn.Long):
		strcat(Type,"long int")
	elif(syn.Short):
		strcat(Type,"short int")
	elif((syn.Type == T_Int)):
		strcat(Type,"int")
	elif((syn.Type == T_Char)):
		if(syn.width==1):
			 strcat(Type,"char")
		elif(syn.width==2) :
			strcat(Type,"wchar_t")
		else:
			print "Line" ,linecount, ": error: error in type computation.\n"
	elif((syn.Type == T_Bool)) :
		strcat(Type,"bool")
	elif((syn.Type == T_Float)):
		if(syn.width==4):
			 strcat(Type,"float")
		elif(syn.width==8):
			 strcat(Type,"double")
		else :
			print "Line" ,linecount, ": error: error in type computation.\n"
	elif(syn.Type[0] != '\0') :
		Type = syn.Type
	else:
		Type = "void"
	if(syn.ptr):
		 strcat(Type,"*")
	if(syn.doubleptr):
		 strcat(Type,"*")
	result = ""
	result = Type
	return result
	
def AddType(id1,scope,type1):
	newNode=symentry()
	newNode.idName=id1
	#print id1
	newNode.scope=scope
	newNode.type=type1
	#print newNode.idName[0]
	#print ord(newNode.idName[0])%HashSize
	newNode.next=scopeTable[ord(newNode.idName[0])%HashSize]	# again conversion of char to int not by default
	return scopeTable[ord(newNode.idName[0])%HashSize]

def SetScopeLabel(id1, scope, off):
	temp=scope
	scopeTable[ord(id1[0])%HashSize].labelScope=temp
	scopeTable[ord(id1[0])%HashSize].heapOffset=off

def SetStackOffset(id1,off):
	scopeTable[ord(id1[0])%HashSize].stackOffset=off


def lookupType(id1,scope):
	list1=symentry()
	# python by defualt char ko int mein convert nahin karta hai.... pehle char mein int mein ord() use karke convert karte hain.
	#list1=scopeTable[id1[0]%HashSize]
	list1=scopeTable[ord(id1[0])%HashSize]
	while (list1!=None and list1.idName!=id1 and list1.scope==scope):
		list1=list1.next
	if(list1!=None and list1.idName==id1 and list1.scope==scope):
		return list1.type
	##return None


def lookupId(id1,scope):
	list1=scopeTable[ord(id1[0])%HashSize]
	#print list1
	while (list1!=None and list1.idName!=id1 and list1.scope==scope):
		list1=list1.next
	if(list1!=None and list1.idName==id1 and list1.scope==scope):
		return list1
	return None

def lookupConst (id1, scope):
	list1 = scopeTable[id1[0]%HashSize]
	while(list1!=None and list1.idName!=id1 and list1.scope==scope):
		list1 = list1.next
	if(list1!=None and list1.idName==id1 and list1.scope==scope):
		return list1.Const
	return -1


def lookupptrConst (id1, scope1):
	list1 = scopeTable[id1[0]%HashSize]
	while(list1!=None and list1.idName!=id1 and list1.scope==scope):
		list1 = list1.next
	if(list1!=None and list1.idName==id1 and list1.scope==scope):
		return list1.ptrConst
	return -1

def lookupptr (id1, scope1):
	list1 = scopeTable[id1[0]%HashSize]
	while(list1!=None and list1.idName!=id1 and list1.scope==scope):
		list1 = list1.next
	if(list1!=None and list1.idName==id1 and list1.scope==scope):
		return list1.ptr
	return -1

def setValue(id1,scope,val):
	list1 = scopeTable[id1[0]%HashSize]
	while(list1!=None and not (list1.idName!=id1 and list1.scope!=scope)):
		list1 = list1.next
	list1.v = val

def deleteScope(scope):
	for i in range(HashSize):
		list1 = scopeTable[i]
		prevList = symentry()
		head=symentry()
		while(list1!=None):
			if(list1.scope==scope):
				if(prevList!=None):
					prevList.next=list1.next
				list1 = list1.next
			else:
				if(prevList == None):
					head = list1
					prevList=list1
					list1=list1.next
				else:
					prevList=list1
					list1=list1.next		
		scopeTable[i] = head

def recursiveLookupType (id1,scope):
       if(scope=="global"):
               return lookupType(id1, scope)
       else:
               temp = lookupType(id1, scope)
               if(temp!=None):
                       return temp
               else:
                       l = len(scope)
                       t=scope
                       for i in range(l,0,-1):
                               if(t[l] == ','):
                                       t[l] = '\0'
                                       break
                       return recursiveLookupType(id1, t)

def recursiveLookupId (id1, scope):
       if(scope=="global,0"):
               return lookupId(id1, scope)
       else:
               temp = lookupId(id1, scope)
               if(temp!=None):
                       return temp
               else:
                       l = len(scope)
		       t=scope
                       for i in range(l,0,-1):
                               if(t[l] == ','):
                                       t[l] = '\0'
                                       break
                       return recursiveLookupId(id1, t)

def getValue(id1, scope):
	list1 = scopeTable[id1[0]%HashSize]
	while(list1!=None and not(list11idName!=id1 and list1.scope!=scope)):
		list1 = list1.next
	return list1.v

def initializeScopeTable():
	for i in range(HashSize):
		scopeTable[i] = None
	
def newTemp(width):
	off = global_variables.offset[currentDepth]
	global_variables.offset[currentDepth] = global_variables.offset[currentDepth] + width
	return off
l=0
t=0
def newLabel():
	buffer1="$label"+str(l)
	#print buffer1
	temp=buffer1
	return temp

def replicate(str1):
	temp=str1
	return temp

def append(str1,str2):
	return str1+str2


def gen(instr, reg, addr):
	print addr
	t=instr+" "+reg+","+buf
	return t


def compareParameterList(funNode,parameterlist):
	temp2 = parameterlist
	i=0
	while(i<funNode.functionOverloading):
		temp1 = funNode.parameterList[i]
		temp2 = parameterlist
		while(1):
			if(temp1==None and temp2 == None):
				return 1
			elif(temp1 == None or temp2 == None):
				break
			elif(temp1.type==temp2.type):
				break
			else:
				if(temp1==None):
					return 1
				temp1=temp1.next
				temp2=temp2.next
		i=i+1
	return 0

def compareParameterIndex(funNode,parameterlist):
	temp2 = parameterlist
	i=0
	while(i<funNode.functionOverloading):
		temp1 = funNode.parameterList[i]
		temp2 = parameterlist
		while(1):
			if(temp1==None and temp2 == None):
				return i
			elif(temp1 == None or temp2 == None):
				break
			elif(temp1.type==temp2.type):
				break
			else:
				if(temp1==None):
					return 1
				temp1=temp1.next
				temp2=temp2.next
		i=i+1
	return -1

def printout(parameterlist):
	temp = parameterlist
	while(len(temp)!=0):
	#while(temp!=Null):
		#temp = temp.peek
		temp.pop()

def expressionListCode(expressionList,function):
	code=replicate("")
	i=0
	temp2 = expressionList
	while(i<function.functionOverloading):
		temp1 = function.parameterList[i]
		temp2 = expressionList
		code = replicate("")
		while(1):
			if(temp1==None and temp2 == None):
				return code
			elif(temp1 == None):
				break
			elif(temp2 == None):
			    	break
			elif(temp1.type==temp2.type):
			    	break
			else:		
				code = append(code,gen("lw","$t1",temp2.stackOffset))
				code = append(code,"($sp)\n")
				code = append(code,gen("sw","$t1",temp1.stackOffset))
				code = append(code,"($t9)\n")
				temp1=temp1.next
				temp2=temp2.next
		i=i+1
	return code


